<template>
  <!--组件框-->
  <div tabindex="0" :class="screenMove?'move':''" class="componentBox" :style="getStyle()" :id="id">
    <span class="r" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="l" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="t" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="b" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="br" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="bl" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="tr" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <span class="tl" v-show="chooseComponent!=null && chooseComponent.uuid==id"></span>
    <div class="slotBox" :class="screenMove?'eventsNone':''">
      <slot  ></slot>
    </div>
  </div>
</template>

<script>
  import * as u from '@/util/util'
  import * as d3 from 'd3'

  export default {
    name: "componentBox",
    props: {
      id: String,
      option: {
        type: Object,
        default: {
          width: 0,      //box宽度
          height: 0,     //box高度
          left: 0,       //定位x
          top: 0,        //定位y
        }
      },
    },
    computed: {
      //判断是否可以操作dom
      screenMove() {
        return this.$store.state.screenMove
      },

      //当前选中的值
      chooseComponent() {
        return this.$store.state.chooseComponent
      },
    },

    data() {
      return {
        //面板宽高
        width: 0,
        height: 0,
        //宽高缩放值
        w: 1,
        h: 1,
      }
    },
    mounted() {
      this.init();
    },
    methods: {


      /**
       * 元素缩放动作
       */
      zoomAction() {
        var vm = this;
        //获取dom元素
        let oDiv = document.getElementById(this.id);
        //获取dom元素下的span
        var aSpan = oDiv.getElementsByTagName('span')
        for (var i = 0; i < aSpan.length; i++) {
          let obj = aSpan[i];
          /*记录方法内部所需参数*/
          var oldWidth;           //dom本身的宽度
          var oldHeight;          //dom本身的高度
          var oldX;               //当前鼠标位置距离body的x坐标
          var oldY;               //当前鼠标位置距离body的y坐标
          var oldLeft;            //dom元素距离容器的左边界的位置
          var oldTop;             //dom元素距离容器上边界的位置
          d3.select(aSpan[i]).call(
            d3.drag()
              .on('drag', e => {
                if (!this.screenMove) {
                  return;
                }
                var temp = e.sourceEvent
                var oEv = {
                  clientX: temp.clientX,
                  clientY: temp.clientY
                }

                if (obj.className == 'tl') {
                  let left = oldLeft + (oEv.clientX - oldX);
                  let top = oldTop + (oEv.clientY - oldY);
                  let width = oldWidth - (oEv.clientX - oldX);
                  let height = oldHeight - (oEv.clientY - oldY);
                  if (width < 1 || height < 1) {
                    return
                  }
                  /!*底边判断*!/
                  if (left >= 0) {
                    vm.option.width = width
                    vm.option.left = left
                  }
                  if (top >= 0) {
                    vm.option.height = height
                    vm.option.top = top
                  }

                } else if (obj.className == 'bl') {
                  let left = oldLeft + (oEv.clientX - oldX)
                  let width = oldWidth - (oEv.clientX - oldX)
                  let height = oldHeight + (oEv.clientY - oldY)

                  //收缩最小判断
                  if (width < 1 || height < 1) {
                    return
                  }
                  if (left >= 0) {
                    vm.option.width = width
                    vm.option.left = left
                  }
                  //底部顶边判断 TODO(容器高度>dom元素距离顶部的高度+dom本身的高度+鼠标移动的高度)
                  if (vm.height > oldTop + oldHeight + (oEv.clientY - oldY)) {
                    vm.option.height = height

                  }

                } else if (obj.className == 'tr') {
                  let right = oldLeft - (oEv.clientX - oldX)
                  let top = oldTop + (oEv.clientY - oldY)
                  let width = oldWidth + (oEv.clientX - oldX)
                  let height = oldHeight - (oEv.clientY - oldY)
                  if (width < 1 || height < 1) {
                    return
                  }
                  //右边顶边判断 TODO(容器宽度-边框>dom元素距离左边的宽度+dom本身的宽度+鼠标移动的宽度)
                  if (vm.width > oldLeft + oldWidth + (oEv.clientX - oldX)) {
                    vm.option.width = width
                    vm.option.right = right
                  }
                  if (top >= 0) {
                    vm.option.height = height
                    vm.option.top = top
                  }
                } else if (obj.className == 'br') {
                  let right = oldLeft - (oEv.clientX - oldX)
                  let width = oldWidth + (oEv.clientX - oldX)
                  let height = oldHeight + (oEv.clientY - oldY)
                  //收缩最小判断
                  if (width < 1 || height < 1) {
                    return
                  }
                  //右边顶边判断 TODO(容器宽度-边框>dom元素距离左边的宽度+dom本身的宽度+鼠标移动的宽度)
                  if (vm.width > oldLeft + oldWidth + (oEv.clientX - oldX)) {
                    vm.option.width = width
                    vm.option.right = right
                  }

                  //底部顶边判断 TODO(容器高度>dom元素距离顶部的高度+dom本身的高度+鼠标移动的高度)
                  if (vm.height > oldTop + oldHeight + (oEv.clientY - oldY)) {
                    vm.option.height = height
                  }

                } else if (obj.className == 't') {
                  let height = oldHeight - (oEv.clientY - oldY)
                  let top = oldTop + (oEv.clientY - oldY)
                  if (height < 1) {
                    return
                  }
                  if (top >= 0) {
                    vm.option.top = top
                    vm.option.height = height
                  }
                } else if (obj.className == 'b') {
                  let height = oldHeight + (oEv.clientY - oldY)
                  if (height < 1) {
                    return
                  }
                  //底部顶边判断 TODO(容器高度>dom元素距离顶部的高度+dom本身的高度+鼠标移动的高度)
                  if (vm.height > oldTop + oldHeight + (oEv.clientY - oldY)) {
                    vm.option.height = height
                  }
                } else if (obj.className == 'l') {
                  let left = oldLeft + (oEv.clientX - oldX)
                  let width = oldWidth - (oEv.clientX - oldX)
                  if (width < 1) {
                    return
                  }
                  if (left >= 0) {
                    vm.option.width = width
                    vm.option.left = left
                  }

                } else if (obj.className == 'r') {
                  let right = oldLeft - (oEv.clientX - oldX)
                  let width = oldWidth + (oEv.clientX - oldX)
                  if (width < 1) {
                    return
                  }
                  //右边顶边判断 TODO(容器宽度-边框>dom元素距离左边的宽度+dom本身的宽度+鼠标移动的宽度)
                  if (vm.width > oldLeft + oldWidth + (oEv.clientX - oldX)) {
                    vm.option.width = width
                    vm.option.right = right
                  }
                }
              })
              .on('start', e => {
                var oEv = e || event
                let oDiv = document.getElementById(this.id);
                oldX = oEv.sourceEvent.clientX;                //当前鼠标位置距离body的x坐标
                oldY = oEv.sourceEvent.clientY;                //当前鼠标位置距离body的y坐标
                oldWidth = oDiv.offsetWidth        //dom本身的宽度
                oldHeight = oDiv.offsetHeight      //dom本身的高度
                oldLeft = oDiv.offsetLeft          //dom元素距离容器的左边界的位置
                oldTop = oDiv.offsetTop            //dom元素距离容器上边界的位置
              })
              .on('end', e => {
                //拖拽结束
              })
          )
        }
      },


      /**
       * 元素移动函数
       */
      moveAction() {
        let dom = document.getElementById(this.id);
        let oDivThisEv = null          //鼠标按下的位置
        let distanceX = null       //计算鼠标按下个相对dom的位置
        let distanceY = null       //计算鼠标按下个相对dom的位置
        d3.select(dom).call(
          d3.drag()
            .on('drag', e => {
              if (!this.screenMove) {
                return;
              }
              //计算拖拽了多少距离
              let left = e.x - distanceX
              let top = e.y - distanceY;
              this.option.left = u.toFixed(left / this.w, 2);
              this.option.top = u.toFixed(top / this.h, 2);
            })
            .on('start', e => {
              //拖拽开始
              oDivThisEv = e.sourceEvent
              distanceX = (oDivThisEv.x) - dom.getBoundingClientRect().x
              distanceY = (oDivThisEv.y) - dom.getBoundingClientRect().y
            })
            .on('end', e => {
              //拖拽结束
            })
        )
      },



      /**
       * 样式设置
       */
      getStyle() {
        return {
          "width": this.option.width + "px",
          "height": this.option.height + "px",
          "left": this.option.left + "px",
          "top": this.option.top + "px",
        }
      },

      /**
       * 初始化
       */
      init() {
        this.width = this.$store.state.panelDom.width;
        this.height = this.$store.state.panelDom.height;
        this.w = this.$store.state.panelDom.w;
        this.h = this.$store.state.panelDom.h;
        this.moveAction();
        this.zoomAction();
      }
    }
  }
</script>

<style scoped lang="less">
  .componentBox {
    position: absolute;
    cursor: Default;
    .slotBox {
      width: 100%;
      height: 100%;
      overflow: hidden
    }
    .t, .b, .l, .r {
      z-index: 50000 !important;
      position: absolute;
      background: #fff;
      border: 1px solid #59c7f9;
      width: 1px;
      height: 1px;

    }

    .l, .r {
      width: 1px;
      height: 100%;
      cursor: col-resize;
    }

    .t, .b {
      width: 100%;
      height: 1px;
      cursor: row-resize;
    }

    .t {
      top: -2px;
    }

    .b {
      bottom: -2px;
    }

    .l {
      left: -2px;
    }

    .r {
      right: -2px;
    }

    .tl, .bl, .br, .tr {
      z-index: 50000 !important;
      position: absolute;
      background: #fff;
      border: 1px solid #59c7f9;
      border-radius: 50%;
      width: 10px;
      height: 10px;
      cursor: nwse-resize

    }

    .tl, .bl {
      left: -6px;
    }

    .tr, .br {
      right: -6px;
    }

    .br, .bl {
      bottom: -6px;
    }

    .tl, .tr {
      top: -6px;
    }

    .tr, .bl {
      cursor: nesw-resize;
    }
  }
  .move{
    z-index: 999999;
  }
  .move:hover {
    background-color: rgba(115, 170, 229, .5);
    cursor: Move;
  }

  .move:active {
    background-color: rgba(115, 170, 229, .5);
    cursor: Move;
  }
  /*事件穿透方式dom拖拽事件丢失*/
  .eventsNone{
    pointer-events: none
  }
</style>
